package com.coolgor.axnut.schedule.lordsee;

import com.coolgor.axnut.dto.lordsee.ScanIPResultExecution;
import com.coolgor.axnut.dto.lordsee.ScanSegmentExecution;
import com.coolgor.axnut.entity.lordsee.ScanIPResult;
import com.coolgor.axnut.entity.lordsee.ScanSegment;
import com.coolgor.axnut.enums.lordsee.ScanSegmentOperationStateEnum;
import com.coolgor.axnut.exceptions.lordsee.ScanIPResultOperationException;
import com.coolgor.axnut.service.lordsee.ScanIPResultService;
import com.coolgor.axnut.service.lordsee.ScanSegmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class ScanNetTask {

    @Autowired
    private ScanSegmentService scanSegmentService;

    @Autowired
    private ScanIPResultService scanIPResultService;

    /** 每天凌晨1点
     *  扫描全区设备是否关机
     *  如果有则新增一条未关机记录
     */ // http://cron.qqe2.com/
//	@Scheduled(cron = "0 0/1 * * * ? ") //测试用 每分钟执行一次
//    @Scheduled(cron = "0 30 1,13 * * ? ") //每天凌晨1点和中午13点执行扫描
    @Scheduled(cron = "0 15 3 * * ? ")
    public void scanShutdown() {
        long startTime = System.currentTimeMillis();
        System.out.println(">>开始执行不关机扫描程序：");
        this.scanShutdown2();
        System.out.println(">>程序运行时间：" + (System.currentTimeMillis() - startTime)/1000 + "s");
    }


    /**
     * 通过InetAddress类来监测电脑是否开机
     */
    public void scanShutdown1() {
        ScanIPResult scanIPResult ;
        ScanSegment scanSegmentCondition = new ScanSegment();
        ScanSegmentExecution scanSegmentExecution = scanSegmentService.getScanSegmentList(scanSegmentCondition,0,999);
        if (null != scanSegmentExecution && scanSegmentExecution.getCount()>0 ) {
            String[] segmentStart ;
            String[] segmentEnd ;
            int[] seg1 = new int[4];
            int[] seg2 = new int[4];
            List<ScanSegment> scanSegmentList = scanSegmentExecution.getList();
            for (ScanSegment segment : scanSegmentList ) {
                if (null==segment.getFlag() || "0".equals(segment.getFlag())) {
                    continue; //如果flag是0则不扫描
                }
                System.out.println(" >>>>开始扫描 "+segment.getSegmentStart());
                segmentStart = segment.getSegmentStart().split("\\.");
                seg1[0] = Integer.parseInt(segmentStart[0]);
                seg1[1] = Integer.parseInt(segmentStart[1]);
                seg1[2] = Integer.parseInt(segmentStart[2]);
                seg1[3] = Integer.parseInt(segmentStart[3]);
                segmentEnd = segment.getSegmentEnd().split("\\.");
                seg2[0] = Integer.parseInt(segmentEnd[0]);
                seg2[1] = Integer.parseInt(segmentEnd[1]);
                seg2[2] = Integer.parseInt(segmentEnd[2]);
                seg2[3] = Integer.parseInt(segmentEnd[3]);
                int temp ;
                if ( seg1[0] > seg2[0] ) {
                    temp = seg1[0];
                    seg1[0] = seg2[0];
                    seg2[0] = temp;
                }
                if ( seg1[1] > seg2[1] ) {
                    temp = seg1[1];
                    seg1[1] = seg2[1];
                    seg2[1] = temp;
                }
                if ( seg1[2] > seg2[2] ) {
                    temp = seg1[2];
                    seg1[2] = seg2[2];
                    seg2[2] = temp;
                }
                if ( seg1[3] > seg2[3] ) {
                    temp = seg1[3];
                    seg1[3] = seg2[3];
                    seg2[3] = temp;
                }
                //开始扫描
                InetAddress addip;
                String ip ;
                for (int ip0=seg1[0]; ip0<=seg2[0]; ip0++) {
                    for (int ip1=seg1[1]; ip1<=seg2[1]; ip1++) {
                        for (int ip2=seg1[2]; ip2<=seg2[2]; ip2++) {
                            for (int ip3=seg1[3]; ip3<=seg2[3]; ip3++) {
                                try {
                                    ip = ip0+"."+ip1+"."+ip2+"."+ip3;
                                    addip = InetAddress.getByName(ip); //获取登录过的设备
                                    if (!ip.equals(addip.getHostName())) {
                                        //检查设备是否在线，其中100ms指定的是超时时间
                                        boolean status = InetAddress.getByName(addip.getHostName()).isReachable(100);     // 当返回值是true时，说明host是可用的，false则不可。
                                        // System.out.println("IP地址为:" + ip + "\t\t设备名称为: " + addip.getHostName() + "\t\t是否可用: " + (status ? "可用" : "不可用"));
                                        scanIPResult = new ScanIPResult();
                                        scanIPResult.setIp(ip);
                                        scanIPResult.setHostname(addip.getHostName());
                                        scanIPResult.setStatus(status ? "可用" : "不可用");
                                        scanIPResult.setScanTime(new Date());
                                        scanIPResultService.addScanIPResult(scanIPResult);
                                    }
                                } catch (java.io.IOException uhe) {
                                    System.err.println("Unable to find: " + uhe.getLocalizedMessage());
                                } catch (ScanIPResultOperationException se) {
                                    System.err.println("Unable to add ScanIPResult: " + se.getLocalizedMessage());
                                }
                            }
                        }
                    }
                }
            }
        } else {
            //数据库中没有需要扫描的网段
            scanIPResult = new ScanIPResult();
            scanIPResult.setScanTime(new Date());
            scanIPResult.setStatus("没有需要扫描的网段");
            try {
                scanIPResultService.addScanIPResult(scanIPResult);
            } catch (ScanIPResultOperationException se) {
                System.err.println("Unable to add ScanIPResult: " + se.getLocalizedMessage());
            }
        }
    }

    /**
     * 通过ping来检查电脑是否开机
     */
    public void scanShutdown2() {
        ScanIPResult scanIPResult ;
        ScanSegment scanSegmentCondition = new ScanSegment();
        ScanSegmentExecution scanSegmentExecution = scanSegmentService.getScanSegmentList(scanSegmentCondition,0,999);
        if (null != scanSegmentExecution && scanSegmentExecution.getCount()>0 ) {
            String[] segmentStart ;
            String[] segmentEnd ;
            int[] seg1 = new int[4];
            int[] seg2 = new int[4];
            List<ScanSegment> scanSegmentList = scanSegmentExecution.getList();
            for (ScanSegment segment : scanSegmentList ) {
                if (null==segment.getFlag() || "0".equals(segment.getFlag())) {
                    continue; //如果flag是0则不扫描
                }
                System.out.println(" >>>>开始扫描 "+segment.getSegmentStart());
                segmentStart = segment.getSegmentStart().split("\\.");
                seg1[0] = Integer.parseInt(segmentStart[0]);
                seg1[1] = Integer.parseInt(segmentStart[1]);
                seg1[2] = Integer.parseInt(segmentStart[2]);
                seg1[3] = Integer.parseInt(segmentStart[3]);
                segmentEnd = segment.getSegmentEnd().split("\\.");
                seg2[0] = Integer.parseInt(segmentEnd[0]);
                seg2[1] = Integer.parseInt(segmentEnd[1]);
                seg2[2] = Integer.parseInt(segmentEnd[2]);
                seg2[3] = Integer.parseInt(segmentEnd[3]);
                int temp ;
                if ( seg1[0] > seg2[0] ) {
                    temp = seg1[0];
                    seg1[0] = seg2[0];
                    seg2[0] = temp;
                }
                if ( seg1[1] > seg2[1] ) {
                    temp = seg1[1];
                    seg1[1] = seg2[1];
                    seg2[1] = temp;
                }
                if ( seg1[2] > seg2[2] ) {
                    temp = seg1[2];
                    seg1[2] = seg2[2];
                    seg2[2] = temp;
                }
                if ( seg1[3] > seg2[3] ) {
                    temp = seg1[3];
                    seg1[3] = seg2[3];
                    seg2[3] = temp;
                }
                //开始扫描
                List ipList ;
                String ip ;
                ScanShutdownRunnable scanNetRunnable;//扫描操作的线程
                ScanIPResultExecution exe ;
                for (int ip0=seg1[0]; ip0<=seg2[0]; ip0++) {
                    for (int ip1=seg1[1]; ip1<=seg2[1]; ip1++) {
                        for (int ip2=seg1[2]; ip2<=seg2[2]; ip2++) {
                            ipList = new ArrayList();
                            for (int ip3=seg1[3]; ip3<=seg2[3]; ip3++) {
                                ip = ip0+"."+ip1+"."+ip2+"."+ip3;
                                ipList.add(ip);
                            }
                            if (ipList.size()>0){
                                scanNetRunnable = new ScanShutdownRunnable();
                                scanNetRunnable.setList(ipList);
                                try {
                                    new Thread(scanNetRunnable, "thread-A").start();
                                    Thread.sleep(1);
                                    new Thread(scanNetRunnable, "thread-B").start();
                                    Thread.sleep(1);
                                    new Thread(scanNetRunnable, "thread-C").start();
                                    Thread.sleep(1);
                                    new Thread(scanNetRunnable, "thread-D").start();
                                    Thread.sleep(3*60*1000);
                                }catch ( InterruptedException e ) {
                                    e.printStackTrace();
                                }
                                List<String> result = scanNetRunnable.getResult();
                                if (null!=result && result.size()>0) {
                                    for (String e : result){
                                        scanIPResult = new ScanIPResult();
                                        scanIPResult.setIp(e);
                                        scanIPResult.setStatus("ping");
                                        scanIPResult.setScanTime(new Date());
                                        System.out.println(scanIPResult.getIp());
                                        exe = scanIPResultService.addScanIPResult(scanIPResult);
                                        if (exe.getState()!= ScanSegmentOperationStateEnum.SUCCESS.getState()){
                                            System.out.println(exe.getStateInfo());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } else {
            //数据库中没有需要扫描的网段
            scanIPResult = new ScanIPResult();
            scanIPResult.setScanTime(new Date());
            scanIPResult.setStatus("没有需要扫描的网段");
            try {
                scanIPResultService.addScanIPResult(scanIPResult);
            } catch (ScanIPResultOperationException se) {
                System.err.println("Unable to add ScanIPResult: " + se.getLocalizedMessage());
            }
        }
    }

}